/**
 * 给一个树，选出N/2个点对，使得SIGMA{d(u,v)}最大。
 * 就是要求每一对点的路径都要通过重心。
 * 对于双重心的情况，此时N必然是偶数。只需要把两个重心各自的子节点配对即可。
 * 对于单重心的情况，将各个子树的节点分开放好，依次取出配对。为了防止有子树剩下
 * 每次需要取出当前剩下节点最多的子树与其他子树配对。
 * 如果N是偶数，取完之后还剩最后一个节点，与重心配对即可。
 */
#include <bits/stdc++.h>
#include <bits/extc++.h>
using namespace std;

using llt = long long;
using vi = vector<int>;
using vll = vector<llt>;
using pii = pair<int, int>;
using pll = pair<llt, llt>;

llt const MOD = 998244353LL;

int N;
vector<vi> G;
vi Size;
vi Center;
int CurT;
vector<pii> Ans;

void dfs(int u, int p){
    Size[u] = 1;
    int t = 0;
    for(auto v : G[u]){
        if(v == p) continue;

        dfs(v, u);
        Size[u] += Size[v];
        t = max(t, Size[v]);
    }

    if(t < N - Size[u]) t = N - Size[u];

    if(t < CurT){
        Center.clear();
        Center.push_back(u);
        CurT = t;
    }else if(t == CurT){
        Center.push_back(u);
    }

    return;
}

void proc2(){
    int a = Center[0];
    int b = Center[1];
    vi va, vb;

    function<void(int, int, vi&)> __dfs = [&](int u, int p, vi & vec){
        vec.emplace_back(u);
        for(auto v : G[u]){
            if(v == p) continue;
            __dfs(v, u, vec);
        }
        return;
    };

    va.emplace_back(a);
    for(auto v : G[a]){
        if(v == b) continue;

        __dfs(v, a, va);
    }

    vb.emplace_back(b);
    for(auto v : G[b]){
        if(v == a) continue;

        __dfs(v, b, vb);
    }

    for(int i=0;i<va.size();++i){
        Ans.emplace_back(va[i], vb[i]);
    } 

    return;
}

void proc1(){
    function<void(int, int, vi &)> __dfs = [&](int u, int p, vi & vec){
        vec.emplace_back(u);
        for(auto v : G[u]){
            if(v == p) continue;
            __dfs(v, u, vec);
        }
    };

    vector<vi> vec;
    for(auto v : G[Center[0]]){
        vec.emplace_back(vi());
        __dfs(v, Center[0], vec.back());
    }    

    multiset<int, function<bool(int, int)>> ss([&](int a, int b)->bool{return vec[a].size() < vec[b].size();});
    for(int i=0;i<vec.size();++i) ss.insert(i);

    while(ss.size() > 1){
        int a = *ss.begin();
        ss.erase(ss.begin());
        int b = *ss.rbegin();
        ss.erase(--ss.end());

        Ans.emplace_back(vec[a].back(), vec[b].back());
        vec[a].pop_back(); vec[b].pop_back();
        if(not vec[a].empty()) ss.insert(a);
        if(not vec[b].empty()) ss.insert(b);
    }

    if(ss.size() == 1){
        auto i = *ss.begin();
        assert(vec[i].size() == 1);
        Ans.emplace_back(Center[0], vec[i].back());
    }
    return;
}

void work(){
    cin >> N;
    G.assign(N + 1, {});
    Size.assign(N + 1, 0);
    for(int a,b,i=1;i<N;++i){
        cin >> a >> b;
        G[a].push_back(b);
        G[b].push_back(a);
    }

    CurT = N + N;
    Center.clear();
    dfs(1, 0);

    assert(Center.size() == 1 or (2 == Center.size() and 0 == N %2));

    Ans.clear();
    
    if(2 == Center.size()) proc2();
    else proc1();
    for(const auto & p : Ans) cout << p.first << " " << p.second << "\n";
    return;
}


int main(){
#ifndef ONLINE_JUDGE
    freopen("z.txt", "r", stdin);
#endif
    ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);	
    
    int nofkase = 1;
	// cin >> nofkase;
	while(nofkase--) work();
	return 0;
}#include <bits/stdc++.h>
#include <bits/extc++.h>
using namespace std;

using llt = long long;
using vi = vector<int>;
using vll = vector<llt>;
using pii = pair<int, int>;
using pll = pair<llt, llt>;

llt const MOD = 998244353LL;

int N;
vector<vi> G;
vi Size;
vi Center;
int CurT;
vector<pii> Ans;

void dfs(int u, int p){
    Size[u] = 1;
    int t = 0;
    for(auto v : G[u]){
        if(v == p) continue;

        dfs(v, u);
        Size[u] += Size[v];
        t = max(t, Size[v]);
    }

    if(t < N - Size[u]) t = N - Size[u];

    if(t < CurT){
        Center.clear();
        Center.push_back(u);
        CurT = t;
    }else if(t == CurT){
        Center.push_back(u);
    }

    return;
}

void proc2(){
    int a = Center[0];
    int b = Center[1];
    vi va, vb;

    function<void(int, int, vi&)> __dfs = [&](int u, int p, vi & vec){
        vec.emplace_back(u);
        for(auto v : G[u]){
            if(v == p) continue;
            __dfs(v, u, vec);
        }
        return;
    };

    va.emplace_back(a);
    for(auto v : G[a]){
        if(v == b) continue;

        __dfs(v, a, va);
    }

    vb.emplace_back(b);
    for(auto v : G[b]){
        if(v == a) continue;

        __dfs(v, b, vb);
    }

    for(int i=0;i<va.size();++i){
        Ans.emplace_back(va[i], vb[i]);
    } 

    return;
}

void proc1(){
    function<void(int, int, vi &)> __dfs = [&](int u, int p, vi & vec){
        vec.emplace_back(u);
        for(auto v : G[u]){
            if(v == p) continue;
            __dfs(v, u, vec);
        }
    };

    vector<vi> vec;
    for(auto v : G[Center[0]]){
        vec.emplace_back(vi());
        __dfs(v, Center[0], vec.back());
    }    

    multiset<int, function<bool(int, int)>> ss([&](int a, int b)->bool{return vec[a].size() < vec[b].size();});
    for(int i=0;i<vec.size();++i) ss.insert(i);

    while(ss.size() > 1){
        int a = *ss.begin();
        ss.erase(ss.begin());
        int b = *ss.rbegin();
        ss.erase(--ss.end());

        Ans.emplace_back(vec[a].back(), vec[b].back());
        vec[a].pop_back(); vec[b].pop_back();
        if(not vec[a].empty()) ss.insert(a);
        if(not vec[b].empty()) ss.insert(b);
    }

    if(ss.size() == 1){
        auto i = *ss.begin();
        assert(vec[i].size() == 1);
        Ans.emplace_back(Center[0], vec[i].back());
    }
    return;
}

void work(){
    cin >> N;
    G.assign(N + 1, {});
    Size.assign(N + 1, 0);
    for(int a,b,i=1;i<N;++i){
        cin >> a >> b;
        G[a].push_back(b);
        G[b].push_back(a);
    }

    CurT = N + N;
    Center.clear();
    dfs(1, 0);

    assert(Center.size() == 1 or (2 == Center.size() and 0 == N %2));

    Ans.clear();
    
    if(2 == Center.size()) proc2();
    else proc1();
    for(const auto & p : Ans) cout << p.first << " " << p.second << "\n";
    return;
}


int main(){
#ifndef ONLINE_JUDGE
    freopen("z.txt", "r", stdin);
#endif
    ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);	
    
    int nofkase = 1;
	// cin >> nofkase;
	while(nofkase--) work();
	return 0;
}